home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / GC / mach_dep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-25  |  11.2 KB  |  357 lines

  1. # include "gc.h"
  2. # include <setjmp.h>
  3.  
  4.  
  5. /* If no assembly calls are anticipated, it is only necessary to port     */
  6. /* the mark_regs routine near the end of the file to your machine.        */
  7. /* The allocobj and allocaobj routines are designed only as an assembly   */
  8. /* language interface.  The definitions of objfreelist and aobjfreelist   */
  9. /* are useful only if in-line allocation code is generated.               */
  10.  
  11. /* Definitions similar to the following make it easier to access the free */
  12. /* lists from an assembly lnguage, or in-line C interface.                */
  13. /* They should be added for other architectures.                          */
  14.  
  15.  
  16. struct __gc_arrays _gc_arrays = { 0 }; 
  17.     /* The purpose of the initialization is to force _gc_arrays */
  18.     /* into the data segment.  The Fortran-based object file    */
  19.     /* format used by many versions of UNIX otherwise makes the */
  20.     /* following impossible.  (Note that some assemblers and    */
  21.     /* linkers, notably those for Sun-3s, don't realize that    */
  22.     /* this is impossible, and simply generate garbage.)        */
  23.  
  24. # ifdef M68K_SUN
  25.     asm(".globl _aobjfreelist");
  26.     asm(".globl _objfreelist");
  27.     asm("_aobjfreelist = __gc_arrays");
  28.     asm("_objfreelist = __gc_arrays+0x804");
  29. # endif
  30. # ifdef SPARC
  31.     asm(".global _aobjfreelist");
  32.     asm(".global _objfreelist");
  33.     asm("_aobjfreelist = __gc_arrays");
  34.     asm("_objfreelist = __gc_arrays+0x804");
  35. # endif
  36. # ifdef VAX
  37.     asm(".globl _aobjfreelist");
  38.     asm(".globl _objfreelist");
  39.     asm(".set _aobjfreelist,__gc_arrays");
  40.     asm(".set _objfreelist,__gc_arrays+0x804");
  41. # endif
  42. # ifdef RT
  43.     asm(".globl _aobjfreelist");
  44.     asm(".globl _objfreelist");
  45.     asm(".set _aobjfreelist,__gc_arrays");
  46.     asm(".set _objfreelist,__gc_arrays+0x804");
  47. # endif
  48.  
  49. /* Call allocobj or allocaobj after first saving at least those registers */
  50. /* not preserved by the C compiler. The register used for return values   */
  51. /* is not saved, since it will be clobbered anyway.                       */
  52. # ifdef RT
  53.     /* This is done in rt_allocobj.s */
  54. # else
  55. #   ifdef M68K_HP
  56.     /* Optimizer is not safe, we want these suckers stored. */
  57. /* #   pragma OPTIMIZE OFF - we claim this is unnecessary if -O flag */
  58. /*                           is not used.  It breaks the collector   */
  59. /*                           on other machines.                      */
  60.     asm("    text");        /* HP/Motorola assembler syntax */
  61.     asm("    global  __allocobj");
  62.     asm("    global  __allocaobj");
  63.     asm("    global  _allocobj");
  64.     asm("    global  _allocaobj");
  65. #   else
  66.     asm("    .text");        /* Default (PDP-11 Unix syntax) */
  67.     asm("    .globl  __allocobj");
  68.     asm("    .globl  __allocaobj");
  69.     asm("    .globl  _allocobj");
  70.     asm("    .globl  _allocaobj");
  71. #   endif
  72.  
  73. # ifdef M68K_SUN
  74.     asm("_allocobj:");
  75.     asm("   link    a6,#0");
  76.     asm("    movl    d1,sp@-");
  77.     asm("    movl    a0,sp@-");
  78.     asm("    movl    a1,sp@-");
  79.     asm("    movl    sp@(20),sp@-");
  80.     asm("    jbsr    __allocobj");
  81.     asm("    addl    #4,sp");
  82.     asm("    movl    sp@+,a1");
  83.     asm("    movl    sp@+,a0");
  84.     asm("    movl    sp@+,d1");
  85.     asm("    unlk    a6");
  86.     asm("    rts");
  87.     
  88.     asm("_allocaobj:");
  89.     asm("    link    a6,#0");
  90.     asm("    movl    d1,sp@-");
  91.     asm("    movl    a0,sp@-");
  92.     asm("    movl    a1,sp@-");
  93.     asm("    movl    sp@(20),sp@-");
  94.     asm("    jbsr    __allocaobj");
  95.     asm("    addl    #4,sp");
  96.     asm("    movl    sp@+,a1");
  97.     asm("    movl    sp@+,a0");
  98.     asm("    movl    sp@+,d1");
  99.     asm("    unlk    a6");
  100.     asm("    rts");
  101. # endif
  102.  
  103. # ifdef M68K_HP
  104.     asm("_allocobj:");
  105.     asm("    link     %a6,&0");
  106.     asm("    mov.l    %d1,-(%sp)");
  107.     asm("    mov.l    %a0,-(%sp)");
  108.     asm("    mov.l    %a1,-(%sp)");
  109.     asm("    mov.l    20(%sp),-(%sp)");
  110.     asm("    jsr      __allocobj");
  111.     asm("    add.l    &4,%sp");
  112.     asm("    mov.l    (%sp)+,%a1");
  113.     asm("    mov.l    (%sp)+,%a0");
  114.     asm("    mov.l    (%sp)+,%d1");
  115.     asm("    unlk     %a6");
  116.     asm("    rts");
  117.     
  118.     asm("_allocaobj:");
  119.     asm("    link     %a6,&0");
  120.     asm("    mov.l    %d1,-(%sp)");
  121.     asm("    mov.l    %a0,-(%sp)");
  122.     asm("    mov.l    %a1,-(%sp)");
  123.     asm("    mov.l    20(%sp),-(%sp)");
  124.     asm("    jsr      __allocaobj");
  125.     asm("    add.l    &4,%sp");
  126.     asm("    mov.l    (%sp)+,%a1");
  127.     asm("    mov.l    (%sp)+,%a0");
  128.     asm("    mov.l    (%sp)+,%d1");
  129.     asm("    unlk     %a6");
  130.     asm("    rts");
  131. # endif /* M68K_HP */
  132.  
  133. # ifdef I386
  134.     asm(".data");
  135.     asm("gc_ret_value: .word 0");
  136.     asm(".word 0");
  137.     asm(".text");
  138.  
  139.     asm("_allocaobj:");
  140.     asm("pushl %ebp");
  141.     asm("movl %esp,%ebp");
  142.     asm("pushal");
  143.     asm("pushl 8(%ebp)");          /* Push orignal argument */
  144.     asm("call __allocaobj");
  145.     asm("popl %ecx");
  146.     asm("movl %eax,gc_ret_value");  /* Save return value */
  147.     asm("popal");
  148.     asm("movl gc_ret_value,%eax");
  149.     asm("leave");
  150.     asm("ret");
  151.  
  152.     asm("_allocobj:");
  153.     asm("pushl %ebp");
  154.     asm("movl %esp,%ebp");
  155.     asm("pushal");
  156.     asm("pushl 8(%ebp)");          /* Push orignal argument */
  157.     asm("call __allocobj");
  158.     asm("popl %ecx");
  159.     asm("movl %eax,gc_ret_value");  /* Save return value */
  160.     asm("popal");
  161.     asm("movl gc_ret_value,%eax");
  162.     asm("leave");
  163.     asm("ret");
  164. # endif
  165.  
  166. # ifdef SPARC
  167.     asm("_allocaobj:");
  168.     asm("    ba    __allocaobj");
  169.     asm("    nop");
  170.     asm("_allocobj:");
  171.     asm("    ba    __allocobj");
  172.     asm("    nop");
  173.     
  174. #   include <sun4/trap.h>
  175.     asm("    .globl    _save_regs_in_stack");
  176.     asm("_save_regs_in_stack:");
  177.     asm("    t    0x3   ! ST_FLUSH_WINDOWS");
  178.     asm("    mov    %sp,%o0");
  179.     asm("    retl");
  180.     asm("    nop");
  181. # endif
  182.  
  183. # ifdef VAX
  184.     asm("_allocobj:");
  185.     asm(".word    0x3e");
  186.     asm("pushl   4(ap)");
  187.     asm("calls   $1,__allocobj");
  188.     asm("ret");
  189.     asm("_allocaobj:");
  190.     asm(".word   0x3e");
  191.     asm("pushl   4(ap)");
  192.     asm("calls   $1,__allocaobj");
  193.     asm("ret");
  194. # endif
  195.  
  196. # ifdef NS32K
  197.     asm("_allocobj:");
  198.     asm("enter [],$0");
  199.     asm("movd r1,tos");
  200.     asm("movd r2,tos");
  201.     asm("movd 8(fp),tos");
  202.     asm("bsr ?__allocobj");
  203.     asm("adjspb $-4");
  204.     asm("movd tos,r2");
  205.     asm("movd tos,r1");
  206.     asm("exit []");
  207.     asm("ret $0");
  208.     asm("_allocaobj:");
  209.     asm("enter [],$0");
  210.     asm("movd r1,tos");
  211.     asm("movd r2,tos");
  212.     asm("movd 8(fp),tos");
  213.     asm("bsr ?__allocaobj");
  214.     asm("adjspb $-4");
  215.     asm("movd tos,r2");
  216.     asm("movd tos,r1");
  217.     asm("exit []");
  218.     asm("ret $0");
  219. # endif
  220.  
  221.  
  222. # if !defined(VAX) && !defined(M68K_SUN) && !defined(M68K_HP)&& !defined(SPARC) && !defined(I386) && !defined(NS32K)
  223.     /* Assembly language interface routines undefined */
  224. # endif
  225.  
  226. # endif
  227.  
  228. /* Routine to mark from registers that are preserved by the C compiler. */
  229. /* This must be ported to every new architecture.  There is a generic   */
  230. /* version at the end, that is likely, but not guaranteed to work       */
  231. /* on your architecture.  Run the test_setjmp program to see whether    */
  232. /* there is any chance it will work.                                    */
  233. mark_regs()
  234. {
  235. #       ifdef RT
  236.       register long TMP_SP; /* must be bound to r11 */
  237. #       endif
  238. #       ifdef VAX
  239.     /* VAX - generic code below does not work under 4.2 */
  240.       /* r1 through r5 are caller save, and therefore     */
  241.       /* on the stack or dead.                            */
  242.       asm("pushl r11");     asm("calls $1,_tl_mark");
  243.       asm("pushl r10");     asm("calls $1,_tl_mark");
  244.       asm("pushl r9");    asm("calls $1,_tl_mark");
  245.       asm("pushl r8");    asm("calls $1,_tl_mark");
  246.       asm("pushl r7");    asm("calls $1,_tl_mark");
  247.       asm("pushl r6");    asm("calls $1,_tl_mark");
  248. #       endif
  249. #       ifdef M68K_SUN
  250.     /*  M68K_SUN - could be replaced by generic code */
  251.       /* a0, a1 and d1 are caller save          */
  252.       /*  and therefore are on stack or dead.   */
  253.     
  254.       asm("subqw #0x4,sp");        /* allocate word on top of stack */
  255.  
  256.       asm("movl a2,sp@");    asm("jbsr _tl_mark");
  257.       asm("movl a3,sp@");    asm("jbsr _tl_mark");
  258.       asm("movl a4,sp@");    asm("jbsr _tl_mark");
  259.       asm("movl a5,sp@");    asm("jbsr _tl_mark");
  260.       /* Skip frame pointer and stack pointer */
  261.       asm("movl d1,sp@");    asm("jbsr _tl_mark");
  262.       asm("movl d2,sp@");    asm("jbsr _tl_mark");
  263.       asm("movl d3,sp@");    asm("jbsr _tl_mark");
  264.       asm("movl d4,sp@");    asm("jbsr _tl_mark");
  265.       asm("movl d5,sp@");    asm("jbsr _tl_mark");
  266.       asm("movl d6,sp@");    asm("jbsr _tl_mark");
  267.       asm("movl d7,sp@");    asm("jbsr _tl_mark");
  268.  
  269.       asm("addqw #0x4,sp");        /* put stack back where it was    */
  270. #       endif
  271.  
  272. #       ifdef M68K_HP
  273.     /*  M68K_HP - could be replaced by generic code */
  274.       /* a0, a1 and d1 are caller save.  */
  275.     
  276.       asm("subq.w &0x4,%sp");    /* allocate word on top of stack */
  277.  
  278.       asm("mov.l %a2,(%sp)"); asm("jsr _tl_mark");
  279.       asm("mov.l %a3,(%sp)"); asm("jsr _tl_mark");
  280.       asm("mov.l %a4,(%sp)"); asm("jsr _tl_mark");
  281.       asm("mov.l %a5,(%sp)"); asm("jsr _tl_mark");
  282.       /* Skip frame pointer and stack pointer */
  283.       asm("mov.l %d1,(%sp)"); asm("jsr _tl_mark");
  284.       asm("mov.l %d2,(%sp)"); asm("jsr _tl_mark");
  285.       asm("mov.l %d3,(%sp)"); asm("jsr _tl_mark");
  286.       asm("mov.l %d4,(%sp)"); asm("jsr _tl_mark");
  287.       asm("mov.l %d5,(%sp)"); asm("jsr _tl_mark");
  288.       asm("mov.l %d6,(%sp)"); asm("jsr _tl_mark");
  289.       asm("mov.l %d7,(%sp)"); asm("jsr _tl_mark");
  290.  
  291.       asm("addq.w &0x4,%sp");    /* put stack back where it was    */
  292. #       endif /* M68K_HP */
  293.  
  294. #       ifdef I386
  295.     /* I386 code, generic code does not appear to work */
  296.       asm("pushl %eax");  asm("call _tl_mark"); asm("addl $4,%esp");
  297.       asm("pushl %ecx");  asm("call _tl_mark"); asm("addl $4,%esp");
  298.       asm("pushl %edx");  asm("call _tl_mark"); asm("addl $4,%esp");
  299.       asm("pushl %esi");  asm("call _tl_mark"); asm("addl $4,%esp");
  300.       asm("pushl %edi");  asm("call _tl_mark"); asm("addl $4,%esp");
  301.       asm("pushl %ebx");  asm("call _tl_mark"); asm("addl $4,%esp");
  302. #       endif
  303.  
  304. #       ifdef NS32K
  305.       asm ("movd r3, tos"); asm ("bsr ?_tl_mark"); asm ("adjspb $-4");
  306.       asm ("movd r4, tos"); asm ("bsr ?_tl_mark"); asm ("adjspb $-4");
  307.       asm ("movd r5, tos"); asm ("bsr ?_tl_mark"); asm ("adjspb $-4");
  308.       asm ("movd r6, tos"); asm ("bsr ?_tl_mark"); asm ("adjspb $-4");
  309.       asm ("movd r7, tos"); asm ("bsr ?_tl_mark"); asm ("adjspb $-4");
  310. #       endif
  311.  
  312. #       ifdef SPARC
  313.       /* generic code will not work */
  314.       save_regs_in_stack();
  315. #       endif
  316.  
  317. #    ifdef RT
  318.         tl_mark(TMP_SP);    /* tl_mark from r11 */
  319.  
  320.         asm("cas r11, r6, r0"); tl_mark(TMP_SP);    /* r6 */
  321.         asm("cas r11, r7, r0"); tl_mark(TMP_SP);    /* through */
  322.         asm("cas r11, r8, r0"); tl_mark(TMP_SP);    /* r10 */
  323.         asm("cas r11, r9, r0"); tl_mark(TMP_SP);
  324.         asm("cas r11, r10, r0"); tl_mark(TMP_SP);
  325.  
  326.         asm("cas r11, r12, r0"); tl_mark(TMP_SP); /* r12 */
  327.         asm("cas r11, r13, r0"); tl_mark(TMP_SP); /* through */
  328.         asm("cas r11, r14, r0"); tl_mark(TMP_SP); /* r15 */
  329.         asm("cas r11, r15, r0"); tl_mark(TMP_SP);
  330. #       endif
  331.  
  332. #     if 0
  333.     /* Generic code                          */
  334.     /* The idea is due to Parag Patel at HP. */
  335.     /* We're not sure whether he would like  */
  336.     /* to be he acknowledged for it or not.  */
  337.     {
  338.         jmp_buf regs;
  339.         register word * i = (word *) regs;
  340.         register word * lim = (word *) (((char *)(regs)) + (sizeof regs));
  341.  
  342.         /* Setjmp on Sun 3s doesn't clear all of the buffer.  */
  343.         /* That tends to preserve garbage.  Clear it.         */
  344.         for (; i < lim; i++) {
  345.             *i = 0;
  346.         }
  347.         (void) _setjmp(regs);
  348.         tl_mark_all(regs, lim);
  349.     }
  350. #     endif
  351.  
  352.       /* other machines... */
  353. #       if !(defined M68K_SUN) && !defined(M68K_HP) && !(defined VAX) && !(defined RT) && !(defined SPARC) && !(defined I386) &&!(defined NS32K)
  354.         --> bad news <--
  355. #       endif
  356. }
  357.